package com.ww.springboot.boot.thread.study.base.lock.lockSupport;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * 描述：
 * park:阻塞
 * unPark:解阻塞
 * <p>
 * 未阻塞前 解阻塞不累计-无效
 *
 * 中断可以打断所有park阻塞
 * interrupt 中断后 park方法不会再等待
 * sleep 可以恢复interrupt 中断状态
 *
 * @author 🧑 ‍wanwei
 * @since 2022-01-22 14:57
 */
@Slf4j
public class lockSupportDemo {
    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    System.out.println("-------阻塞线程");
                    LockSupport.park(Thread.currentThread());
                    LockSupport.park(Thread.currentThread());
                    LockSupport.park(Thread.currentThread());
                    LockSupport.park(Thread.currentThread());
                    LockSupport.park(Thread.currentThread());
                    LockSupport.park(Thread.currentThread());
                    TimeUnit.SECONDS.sleep(1);
                } catch (Exception e) {
                    //log.error("", e);
                }
            }
        });
        thread.start();

//        new Thread(()->{
//            while (true){
//                try {
//                    TimeUnit.SECONDS.sleep(1);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println("---------解阻塞");
//                LockSupport.unpark(thread);
//                thread.interrupted();
//            }
//        }).start();

        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("---------中断");
                thread.interrupt();
            }
        }).start();

    }

//    伪代码
//    park() {
//        if(permit > 0) {
//            permit = 0;
//            return;
//        }
//
//        if(中断状态 == true) {
//            return;
//        }
//
//        阻塞当前线程;  // 将来会从这里被唤醒
//
//        if(permit > 0) {
//            permit = 0;
//        }
//    }



//    interrupt(){
//        if(中断状态 == false) {
//            中断状态 = true;
//        }
//        unpark(this);    //注意这是Thread的成员方法，所以我们可以通过this获得Thread对象
//    }

//    sleep(){//这里我忽略了参数，假设参数是大于0的即可
//        if(中断状态 == true) {
//            中断状态 = false;
//            throw new InterruptedException();
//        }
//
//        线程开始睡觉;
//
//        if(中断状态 == true) {
//            中断状态 = false;
//            throw new InterruptedException();
//        }
//    }

//    park调用后一定会消耗掉permit，无论unpark操作先做还是后做。
//    如果中断状态为true，那么park无法阻塞。
//    unpark会使得permit为1，并唤醒处于阻塞的线程。
//    interrupt()会使得中断状态为true，并调用unpark。
//    sleep() / wait() / join()调用后一定会消耗掉中断状态，无论interrupt()操作先做还是后做。
//

}
